﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Network
{

    public class Msg
    {
        public NetConnection sender; // 消息发送者
        public Package message; // 消息内容
    }

    public class MessageRounter : Common.Singleton<MessageRounter>
    {
        public delegate void MessageHandler<T>(NetConnection sender, T message);
        // 消息队列
        public Queue<Msg> messageQueue = new Queue<Msg>();

        // 消息频道
        public Dictionary<string, Delegate> delegateMap =  new Dictionary<string, Delegate>();

        private int threadCount = 8; // 线程数量
        private int workerCount = 0; // 工作线程数量
        private bool isRunning = false; // 是否运行
        AutoResetEvent threadEvent = new AutoResetEvent(true);

        public void AddMessage( NetConnection sender, Package message)
        {
            // 消息入队
            Msg messageUnit = new Msg();
            messageUnit.sender = sender;
            messageUnit.message = message;
            messageQueue.Enqueue(messageUnit);

            // 发送信号
            threadEvent.Set();

        }

        // 订阅
        public void Subscribe<T>(MessageHandler<T> handler) where T : Google.Protobuf.IMessage
        {
            string messageType = typeof(T).Name;
            if (!delegateMap.ContainsKey(messageType))
            {
                delegateMap.Add(messageType, null);
            }
            delegateMap[messageType] = (MessageHandler<T>)delegateMap[messageType] + handler;

            Console.WriteLine(messageType +" : " + delegateMap[messageType].GetInvocationList().Length);
        }
        // 取消订阅
        public void UnSubscribe<T>(MessageHandler<T> handler) where T : Google.Protobuf.IMessage
        {
            string messageType = typeof(T).Name;
            if (delegateMap.ContainsKey(messageType))
            {
                delegateMap[messageType] = (MessageHandler<T>)delegateMap[messageType] - handler;
            }
        }

        /// <summary>
        /// 启动消息路由
        /// </summary>
        /// <param name="inThreadCount"></param>
        public void Start(int inThreadCount)
        { 
            isRunning = true;
            // 启动线程
            this.threadCount = Math.Clamp(inThreadCount, 1, 64);
            for (int i = 0; i < threadCount; i++)
            {
                ThreadPool.QueueUserWorkItem(OnMessageProcess);
            }
            // 等待线程启动
            while (workerCount < threadCount)
            {
                Thread.Sleep(100);
            }
            
        }
        public void Stop()
        {
            isRunning = false;
            // 清空消息队列
            messageQueue.Clear();
            // 等待线程退出
            while (workerCount > 0)
            {
                threadEvent.Set(); // 发送信号
            }
            Thread.Sleep(50);

        }

        /// <summary>
        /// 处理消息
        /// </summary>
        /// <param name="state"></param>
        private void OnMessageProcess(object? state)
        {
            try
            {
                workerCount = Interlocked.Increment(ref workerCount);
                Console.WriteLine("工作线程启动:" + workerCount);

                // 线程处理业务逻辑
                while (isRunning)
                {
                    if (messageQueue.Count == 0)
                    {
                        threadEvent.WaitOne(); // 等待信号
                        continue;
                    }
                    // 取出消息
                    Msg msg = messageQueue.Dequeue();
                    // 解析
                    if (msg.message != null)
                    {
                        // 请求
                        if (msg.message.Request != null)
                        {
                            // 注册
                            if (msg.message.Request.UserRegisterRequest != null)
                            { 
                                Console.WriteLine("注册请求: 用户ID ：" + msg.message.Request.UserRegisterRequest.Username);
                            }
                            // 登入
                            if (msg.message.Request.UserLoginRequest != null)
                            {
                                Console.WriteLine("登入请求: 用户ID ：" + msg.message.Request.UserLoginRequest.Username);
                            }

                        }
                        // 响应
                        if (msg.message.Response != null)
                        { 
                            
                        }
                            
                    }
                }
            }
            catch { }
            finally 
            {
                // 线程退出
                workerCount = Interlocked.Decrement(ref workerCount);
                Console.WriteLine("工作线程退出");
            }
        }


    }
}
